package librairies.dictionnaire.dico;

import librairies.dictionnaire.interfaces.IDictionnaire;
import librairies.dictionnaire.interfaces.IDonneeDico;
import librairies.liste.interfaces.IListe;
import librairies.liste.interfaces.IListeE;
import librairies.liste.list.ListeDCE;

/**
 * dictionnaire sous forme de liste.
 * 
 * @author mlozach
 * @param <E> type des elements dans le dico
 */
public class DicoListe<E extends IDonneeDico<E>> implements IDictionnaire<E>
{
	private IListeE<E> liste;
	
	/**
	 * constructeur par defaut.
	 */
	public DicoListe() 
	{
		this.liste = new ListeDCE<E>();
	}
	
	/**
	 * constructeur par recopie.
	 * @param file la liste d'entree.
	 */
	public DicoListe(IListe<E> file)
	{
		this();		
		this.addWords(file);
	} 
	
	@Override
	public IDictionnaire<E> addWords(IListe<E> words) 
	{	
		for(int i = 0; i < words.size(); ++i)
		{
			boolean duplic = false;
			for(int j = 0; j < this.liste.size(); ++j)
			{
				if(this.liste.get(j).equals(words.get(i))) duplic = true;
			}
			
			if(!duplic)
			{
				this.liste.add(words.get(i)); 
			}
		}
		
	     boolean ok = true;
	     
	     while(ok)
	     {
	    	 ok=false;

	    	 for(int i = 0; i < this.liste.size() - 1; i++)
	         {
	    		 if((this.liste.get(i).compareTo(this.liste.get(i+1)) > 0))
	    		 {
						E tmp = this.liste.get(i);
						this.liste.set(i , this.liste.get(i + 1));
						this.liste.set(i + 1 , tmp);
						
	                    ok=true;
	    		 }
	         }
	     }
	     
		return this;
	}

	@Override
	public IDictionnaire<E> cutWords(IListe<E> words) 
	{
		if(this.liste == null || this.liste.size() == 0) return this;
    		
		for(int i = 0; i < words.size(); ++i)
		{
			for(int j = 0; j < this.liste.size(); ++j)
			{
				if(this.liste.get(j).equals(words.get(i)))
				{
					this.liste.remove(j);
				}
			}
		}
		
		return this;
	}

	@Override
	public int size() 
	{
		if(this.liste == null)
		{
			return 0;
		}
		
		return this.liste.size();
	}

	@Override
	public boolean exists(E word) 
	{
		for(int i = 0; i < this.liste.size(); ++i)
		{
			if(this.liste.get(i).equals(word))
			{
				return true;
			}
		}
		
		return false;
	}
	
	@Override
	public E getObjet(String word)
	{
		for(int i = 0; i < this.liste.size(); ++i)
		{
			if(this.liste.get(i).getValue().equals(word))
			{
				return this.liste.get(i);
			}
		}
		
		return null;
	}

	@Override
	public IListe<E> commonPrefix(E prefix) 
	{
		boolean ok = true;
		IListeE<E> tmp = new ListeDCE<E>();
		String lePrefixe = prefix.getValue();
		
		for(int i = 0; i< this.liste.size(); ++i)
		{
			ok = true;
			
			for(int j = 0; j < lePrefixe.length(); ++j)
			{
				if(this.liste.get(i).getValue().length() >= lePrefixe.length())
				{
					Character l = this.liste.get(i).getValue().charAt(j);
					Character p = lePrefixe.charAt(j);	
				
					if(!l.equals(p))
					{
						ok = false;
					}
				}
				else
				{
					ok = false;
				}
			}
			
			if(ok)
			{
				tmp.add(this.liste.get(i));
			}
		}

		return tmp;
	}
	
	@Override
	public IListe<E> contains(E prefix) 
	{
		IListeE<E> tmp = new ListeDCE<E>();

		if(prefix == null || prefix.getValue() == null || prefix.getValue().length() == 0) return tmp;
		
		for(int i = 0; i < this.liste.size(); ++i)
		{
			if(this.liste.get(i).getValue() != null && prefix.getValue().contains(this.liste.get(i).getValue()))
			{
				tmp.add(this.liste.get(i));
			}
		}

		return tmp;
	}

	/**
	 * getter and setter.
	 */
	public IListeE<E> getListe() {return this.liste;}
	
	/**
	 * methode object.
	 */
	public String toString()
	{
		String res = "";
		
		for(int i = 0; i < this.liste.size(); i++)
		{
			res += this.liste.get(i) + "\n";
		}
		
		return res;
	}
}